﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace Hsenl.Network {

    public class NetworkPool<T> where T : class {
        private readonly ConcurrentQueue<T> _pool = new();

        public T Rent() {
            if (!this._pool.TryDequeue(out var result)) {
                result = (T)Activator.CreateInstance(typeof(T));
            }

            return result;
        }

        public bool TryRent(out T result) {
            if (!this._pool.TryDequeue(out result)) {
                return false;
            }

            return true;
        }

        public void Return(T value) {
            if (value == null)
                throw new ArgumentNullException($"NetworkPool return '{nameof(value)}' is null!");

            this._pool.Enqueue(value);
        }

        public void Clear() {
            foreach (var item in this._pool) {
                if (item is IDisposable disposable) {
                    disposable.Dispose();
                }
            }

            this._pool.Clear();
        }
    }
}